cygwin下把window下dll文件转换成a或者so文件的方法 您所在的位置:网站首页 dll linux 转so cygwin下把window下dll文件转换成a或者so文件的方法

cygwin下把window下dll文件转换成a或者so文件的方法

2024-05-26 19:30| 来源: 网络整理| 查看: 265

转载请注明出处:  http://blog.csdn.net/nana08/article/details/7374635

总所周知,cygwin只是linux、unix在window下的一个模拟环境。其中cygwin下的一个重要组件cygwin1.dll提供了window下感觉linux的一个posix接口。说白了,在window下只能使用linux下一些与硬件无关的命令,如ls、pwd等,因为他们都在cygwin1.的dll中实现了,但是与平台相关的函数就没有办法啦,例如iptables命令。iptables命令在cygwin下无法使用。

       有时候在做平台移植的时候,例如一个linux下的一个程序移植到window下,使用cygwin可以帮助我们省好多精力。但是问题也随之而来,如果你的程序中包含于平台相关的数据结构,与平台先关的函数、或者与平台相关的库文件,在做移植的时候就会出现问题。

      例如,一个linux程序A,在代码中使用了linux平台下的libpcap,相应的,在cygwin下做移植的时候,就需要用到winpcap,就需要在cygwin下安装winpcap库,但是cygwin是类linux环境,所以只能用.a或者.so文件,所以就需要把winpcap编程成cygwin可以识别的.a或者.so文件。

     以后,在遇到与平台有关的linux程序移植到windows平台的时候,就需要把程序中所用到的库文件由linux版本换成window版本,而且需要的window版本不能是.,lib或者.dll

的形式,必须转或者cygwin所能识别的.a 或者.so版本。

ygwin的gcc编译器使用windows的dll文件一般的步骤是使用pexports或dumpbin程序导出dll的DEF文件

 

其中dumpbin导出的DEF文件需要手动修改,所以推荐使用pexports,做法如下:

 

 pexports libFedTimed.dll > libFedTimed.def

 

 dlltool -D libFedTimed.dll -d libFedTimed.def-l libFedTimed.a -k

 

 

 

如果该dll是C的函数库,如libmysql.dll或者kernel32.dll类的DLL,这样做就一点问题没有,直接使用。

 

但是如果是VC6、VC7生成的C++库则存在C/C++ 轧名规则(name mangling)问题,参见如下表

 

 

 

Compiler void h(int) void h (int, char)void h(void)

GNU GCC 3.x _Z1hi _Z1hic _Z1hv

GNU GCC 2.9x h__Fi h__Fic h__Fv

Intel C++ 8.0 for Linux _Z1hi _Z1hic _Z1hv

Microsoft VC++ v6/v7 ?h@@YAXH@Z ?h@@YAXHD@Z?h@@YAXXZ

Borland C++v3.1 @h$qi @h$qizc @h$qv

OpenVMS C++ V6.5 (ARM mode) H__XI H__XICH__XV

OpenVMS C++ V6.5 (ANSI mode)CXX$__7H__FI0ARG51T CXX$__7H__FIC26CDH77 CXX$__7H__FV2CB06E8

OpenVMS C++ X7.1 IA-64 CXX$_Z1HI2DSQ26A CXX$_Z1HIC2NP3LI4 CXX$_Z1HV0BCA19V

Digital MarsC++ ?h@@YAXH@Z ?h@@YAXHD@Z ?h@@YAXXZ

SunPro CC __1cBh6Fi_v_ __1cBh6Fic_v_ __1cBh6F_v_

HP aC++ A.05.55IA-64 _Z1hi _Z1hic _Z1hv

HP aC++ A.03.45PA-RISC h__Fi h__Fic h__Fv

Tru64 C++V6.5 (ARM mode) h__Xi h__Xic h__Xv

Tru64 C++V6.5 (ANSI mode) __7h__Fi __7h__Fic __7h__Fv

 

 

 

不同编译器生成的导出名称不同,所以在使用Cygwin的gcc编译器链接libFedTimed.a时会出现

 

 undefinedreference to `RTI::FedTimeFactory::makeZero()' tstDMSORti HelloWorld.cpp line442 1225384733078 5683

 

错误

 

因为gcc编译对RTIfedTime::getTime()翻译为:_ZN3RTI14FedTimeFactory8makeZeroEv

 

而DMSO RTI的libFedTimed.dll提供的是:?makeZero@FedTimeFactory@RTI

 

 

 

通过自己的摸索,可以修改libFedTimed.def文件中的导出函数声明为:

 

_ZN3RTI14FedTimeFactory8makeZeroEv=?makeZero@FedTimeFactory@RTI

 

再使用dlltool -DlibFedTimed.dll -d libFedTimed.def -l libFedTimed.a -k生成的.a文件就可以使用了。

 

 

 

这里还有一个小技巧:

 

先将你的源程序编译出来的.o文件使用nm -s Country.o > fungcc3.txt得到针对函数的gcc命名_ZN3RTI14FedTimeFactory8makeZeroEv,但是它不容易分辨出来,再使用c++filt提出可阅读的的函数调用名称

 

cat fungcc3.txt | c++filt > fungcc3read.txt

 

针对VC生成的.def文件,同样可以使用undname恢复函数名称

 

undname libFedTimed.def > funvcread.txt

 

然后对照fungcc3.txt、fungcc3read.txt、libFedTimed.def、funvcread.txt就可以完成轧名规则的变换。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有